// 封装uni请求变成Promise风格
import { pinia } from "@/stores/counter";

interface IConfig {
  baseUrl: string;
  timeout?: number;
  header?: any;
}

interface IOptions {
  url: string;
  headers?: any;
  method?: "GET" | "POST" | "DELETE" | "PUT";
  data?: any;
  showLoading?: boolean;
}

interface IUploadOptions {
  url: string;
  headers?: any;
  method?: "GET" | "POST" | "DELETE" | "PUT";
  data: {
    name: string;
    filePath: any;
  };
}

export interface IReturnRes<T> {
  data?: T;
  msg: string;
  code: number;
  rows?: any[];
  total?: number;
}

export type IRes<T> = Promise<IReturnRes<T>>;

export default class Http {
  private readonly baseUrl: string;
  private readonly timeout: number;
  private readonly header: any;

  constructor(config: IConfig) {
    this.baseUrl = config.baseUrl || "";
    this.timeout = config.timeout || 6000;
    this.header = config.header || {};
  }

  _request<T = any>(options: IOptions): Promise<IReturnRes<T>> {
    // showLoading
    if (!options.showLoading) {
      uni.showLoading({
        title: "",
        fail(result) {
          console.log(result);
        },
      });
    }
    return new Promise((resolve, reject) => {
      uni.request({
        url: this.baseUrl + options.url,
        timeout: this.timeout,
        header: {
          // 请求头带token
          Authorization: "Bearer " + pinia.token,
          ...this.header,
          ...options.headers, // 可以请求时传自定义请求头
          clientid: "e5cd7e4891bf95d1d19206ce24a7b32e",
        },
        method: options.method || "GET",
        data: options.data,
        success: (res: any) => {
          const data: IReturnRes<T> = res.data;
          uni.hideLoading();
          if (data.code === 404) {
            uni.showToast({
              title: data.msg,
              icon: "none",
              duration: 2000,
              fail(result) {
                console.log(result);
              },
            });
          } else if (data.code !== 200) {
            uni.showToast({
              title: data.msg,
              icon: "error",
              fail(result) {
                console.log(result);
              },
              duration: 2000,
            });
            // 需要登录权限
          }
          resolve(data);
        },
        fail: (err: any) => {
          console.log(err);
          uni.hideLoading();
          uni.showToast({
            title: err.errMsg,
            icon: "error",
            fail(result) {
              console.log(result);
            },
          });
          reject(err);
        },
      });
    });
  }

  get<T = any>(options: IOptions): Promise<IReturnRes<T>> {
    return this._request({
      ...options,
    });
  }

  post<T = any>(options: IOptions): Promise<IReturnRes<T>> {
    return this._request({
      ...options,
      method: "POST",
    });
  }

  put<T = any>(options: IOptions): Promise<IReturnRes<T>> {
    return this._request({
      ...options,
      method: "PUT",
    });
  }

  del<T = any>(options: IOptions): Promise<IReturnRes<T>> {
    return this._request({
      ...options,
      method: "DELETE",
    });
  }

  // 上传文件
  upload<T = any>(options: IUploadOptions): Promise<IReturnRes<T>> {
    uni.showLoading({
      title: "上传中",
      fail(result) {
        console.log(result);
      },
    });
    return new Promise((resolve, reject) => {
      uni.uploadFile({
        url: this.baseUrl + options.url,
        header: {
          // 请求头带token
          "Authori-zation": "Bearer " + pinia.token,
          ...options.headers,
        },
        filePath: options.data.filePath,
        name: options.data.name,
        formData: {
          filename: options.data.name,
        },
        success: (res: any) => {
          const data: IReturnRes<T> = res.data;
          uni.hideLoading();
          if (data.code != 200) {
            uni.showToast({
              title: data.msg,
              icon: "none",
              fail(result) {
                console.log(result);
              },
            });
          }
          resolve(data);
        },
        fail: (err: any) => {
          uni.hideLoading();
          uni.showToast({
            title: "请求超时",
            icon: "error",
            fail(result) {
              console.log(result);
            },
          });
          reject(err);
        },
      });
    });
  }
}
